package com.sk.web.exception;

import com.sk.util.SpringUtil;
import com.sk.util.model.Result;
import com.sk.util.model.BusinessException;
import com.sk.util.model.BusinessRemoteException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.ArrayList;
import java.util.List;


/**
 * 全局异常处理。
 *
 * @author smy
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = BusinessException.class)
    @ResponseStatus(HttpStatus.OK)
    public final Result<?> exceptionHandler(BusinessException e) {
        log.warn("业务异常:code={},message={}", e.getCode(), e.getMessage());
        return Result.fail(e.getCode(), e.getMessage(), e.getData());
    }

    @ExceptionHandler(value = BusinessRemoteException.class)
    @ResponseStatus(HttpStatus.OK)
    public final Result<?> exceptionHandler(BusinessRemoteException e) {
        log.warn("调用异常: {}", e.getResult());
        return e.getResult();
    }

    @ExceptionHandler(value = AccessException.class)
    @ResponseStatus(HttpStatus.NOT_ACCEPTABLE)
    public final Result<?> exceptionHandler(AccessException e) {
        log.warn("权限异常:{}", e.getMessage());
        return Result.fail(e.getCode(), SpringUtil.getMessage(e.getMessage(), "权限访问异常"));
    }

    @ExceptionHandler(value = BindException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public final Result<?> exceptionHandler(BindException e) {
        List<String> list = new ArrayList<>();
        for (ObjectError error : e.getBindingResult().getAllErrors()) {
            list.add(error.getDefaultMessage());
        }
        log.error("请求参数错误:{}", list);
        return Result.fail(2, SpringUtil.getMessage("ArgumentNotValidException", "参数错误"), list);
    }

    @ExceptionHandler(value = Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public final Result<?> exceptionHandler(Exception e) {
        log.error("系统错误", e);
        String message = SpringUtil.getMessage(e.getClass().getSimpleName(), "系统错误");
        return Result.fail(1, message);
    }

}
